/*{
author=黑店小小二
version=1.0
date=2022/08/19
}*/

/***
思路设计来源于淡然大佬（大浪淘沙mod作者）跟GaZeLle大佬（风林火山mod作者）,已取得授权。
 「奇袭」科技增加「在森林攻击回复气力」
 「大盾」科技增加「受到攻击时回复气力」
 「强弩」科技增加「弩战法耗气减少」
 「良马产出」科技增加「防御力小幅增加」
 「骑射」科技增加「骑射造成气力杀伤」
 「防卫强化」科技增加「据点X格内敌军几率掉气」
 「港关扩张」科技增加「增加据点与县城金收入」
 「木牛流马」科技增加「增加据点与县城粮收入」
 「政令整备」科技增加「提高行动力回复」
 「掌握人心」科技增加「每月提升据点治安与士气」
***/

// ## 2022/08/19 # 茕茕 # 此包修改，请联系作者黑店小小二，私修出错概不理会 ##
// ## 2022/05/21 # 黑店小小二 # 完成科技加强 ##

namespace 科技加强包
{
  /*[text=开启_科技加强包 tip=开关 default=true]*/
  const bool 开启_科技加强包 = true;
  /*[text=玩家生效 tip=关闭后则只有电脑生效 default=true]*/
  const bool 玩家生效 = true;
  /*[text=掌握人心回复治安数 tip=掌握人心科技额外回复治安数 default=5 min=0 max=100]*/
  const int 掌握人心回复治安数 = 5;
  /*[text=掌握人心回复气力数 tip=掌握人心科技额外回复气力数 default=5 min=0 max=150]*/
  const int 掌握人心回复气力数 = 10;

  class Main
  {

    int 防卫强化减气 = 6;
    int 防卫强化影响范围 = 2;

    pk::func53_t @prev_callback_53;
    pk::func150_t @prev_callback_150;
    pk::func151_t @prev_callback_151;
    pk::func152_t @prev_callback_152;
    pk::func153_t @prev_callback_153;
    pk::func162_t @prev_callback_162;
    pk::func209_t @prev_callback_209;

    array<string> tech = {
      /*枪兵锻练*/ "枪兵战法的威力增加",
      /*兵粮袭击*/ "枪兵在攻击时能夺取敌部队的部分兵粮",
      /*奇袭*/ "在森林地形，枪兵攻击对方不会遭到反击",
      /*精锐枪兵*/ "枪兵的攻击、防御、移动皆大幅强化",

      /*戟兵锻练*/ "戟兵战法的威力增加",
      /*矢盾*/ "面对弓矢攻击，有30％的防御概率",
      /*大盾*/ "面对普通攻击，有30％的防御概率",
      /*精锐戟兵*/ "戟兵的攻击、防御、移动皆大幅强化",

      /*弩兵锻练*/ "弩兵战法的威力增加",
      /*应射*/ "弩兵被弓矢攻击时，可发动反击",
      /*强弩*/ "弩兵及城市反击的射程增加１格",
      /*精锐弩兵*/ "弩兵的攻击、防御、移动皆大幅强化",

      /*骑兵锻练*/ "骑兵战法的威力增加",
      /*良马产出*/ "骑兵的移动力增加",
      /*骑射*/ "骑兵可以使用弓矢攻击",
      /*精锐骑兵*/ "骑兵的攻击、防御、移动皆大幅强化",

      /*熟练兵*/ "兵士的气力上限增加20",
      /*难所行军*/ "可以通过间道和浅滩，过栈道受到的损伤降低",
      /*军制改革*/ "编成部队的兵士上限增加3000",
      /*云梯*/ "部队对据点的攻击力增加",

      /*车轴强化*/ "兵器的移动力增加",
      /*石造建筑*/ "可建造障害物「石壁」、施设「石兵八阵」",
      /*投石开发*/ "可建造兵器「投石、斗舰」、施设「投石台」",
      /*霹雳*/ "投石攻击时、对目标周围的部队造成连锁伤害",

      /*工兵育成*/ "每回合建筑耐久度的回复量增加",
      /*施设强化*/ "可建造军事设施「砦、连弩橹」",
      /*城壁强化*/ "可建造军事设施「城塞」、据点的耐久增加",
      /*防卫强化*/ "据点的反击能力强化",

      /*木兽开发*/ "可建造功城兵器「木兽」",
      /*神火计*/ "火计的施放距离增为３格",
      /*火药炼成*/ "可以制造「火炎种、火炎球」",
      /*爆药炼成*/ "可以建造「业火种、业火球」。火的威力强化",

      /*木牛流马*/ "输送队的移动力增加",
      /*城关扩张*/ "关隘和支城的钱、粮、兵士、兵器上限增加",
      /*政令整备*/ "治安下降速度减慢",
      /*人心掌握*/ "所属武将的忠诚度下降减慢",
    };

    Main()
    {
      pk::bind(102, 1, pk::trigger102_t(onLoadScenario));
      pk::bind(108, pk::trigger108_t(onMonthStart));
      // pk::bind(111, pk::trigger111_t(onTurnStart));
      pk::bind(107, pk::trigger107_t(onNewDay));

      @prev_callback_53 = cast<pk::func53_t @>(pk::get_func(53));
      pk::reset_func(53);
      pk::set_func(53, pk::func53_t(func53));

      @prev_callback_150 = cast<pk::func150_t @>(pk::get_func(150));
      pk::reset_func(150);
      pk::set_func(150, pk::func150_t(func150));

      @prev_callback_151 = cast<pk::func151_t @>(pk::get_func(151));
      pk::reset_func(151);
      pk::set_func(151, pk::func150_t(func151));

      @prev_callback_152 = cast<pk::func152_t @>(pk::get_func(152));
      pk::reset_func(152);
      pk::set_func(152, pk::func152_t(func152));

      @prev_callback_153 = cast<pk::func153_t @>(pk::get_func(153));
      pk::reset_func(153);
      pk::set_func(153, pk::func153_t(func153));

      @prev_callback_162 = cast<pk::func162_t @>(pk::get_func(162));
      pk::reset_func(162);
      pk::set_func(162, pk::func162_t(func162));

      @prev_callback_209 = cast<pk::func209_t @>(pk::get_func(209));
      pk::reset_func(209);
      pk::set_func(209, pk::func209_t(func209));
    }

    bool is_player_effect(pk::force @force)
    {
      return force !is null and force.get_id() < 非贼势力_末 and (玩家生效 or !pk::is_player_controlled(force));
    }

    void onLoadScenario()
    {
      if (开启_科技加强包)
      {
        // pk::get_tech(技巧_奇袭).name = pk::encode("森林奇袭");

        // pk::get_tech(技巧_矢盾).name = pk::encode("弓箭防御");

        // pk::get_tech(技巧_大盾).name = pk::encode("大盾防御");

        // pk::get_tech(技巧_应射).name = pk::encode("弩兵回射");

        // pk::get_tech(技巧_强弩).name = pk::encode("强弩远射");

        // pk::get_tech(技巧_难所行军).name = pk::encode("水军操练");

        // pk::get_tech(技巧_良马产出).name = pk::encode("马铠强化");


        // pk::get_tech(技巧_骑射).name = pk::encode("骑兵突袭");


        // pk::get_tech(技巧_云梯).name = pk::encode("云梯攻城");

        // pk::get_tech(技巧_霹雳).name = pk::encode("霹雳投石");


        pk::get_tech(技巧_枪兵锻练).desc = pk::encode(pk::format("枪兵战法伤害、攻击、防御提高{}%", (UNIT_ATTR::锻炼兵攻防倍率)-100));

        pk::get_tech(技巧_戟兵锻练).desc = pk::encode(pk::format("戟兵战法伤害、攻击、防御提高{}%", (UNIT_ATTR::锻炼兵攻防倍率)-100));

        pk::get_tech(技巧_弩兵锻练).desc = pk::encode(pk::format("弩兵战法伤害、攻击、防御提高{}%", (UNIT_ATTR::锻炼兵攻防倍率)-100));

        pk::get_tech(技巧_骑兵锻练).desc = pk::encode(pk::format("骑兵战法伤害、攻击、防御提高{}%", (UNIT_ATTR::锻炼兵攻防倍率)-100));

        pk::get_tech(技巧_奇袭).desc = pk::encode("森地形攻击不被反击、攻击时回复5点气力");

        pk::get_tech(技巧_矢盾).desc = pk::encode("降低30%所受弓箭伤害,30%概率免疫弓箭攻击");

        pk::get_tech(技巧_大盾).desc = pk::encode("受到伤害时回复3点气力、且30%概率无视普攻");

        pk::get_tech(技巧_强弩).desc = pk::encode("弩兵和城市射程增加、弩战法耗气减少10%");

        pk::get_tech(技巧_良马产出).desc = pk::encode("骑兵的防御力增加、移动力小幅增加");

        pk::get_tech(技巧_骑射).desc = pk::encode("攻击附带冲锋伤害、并可使用骑射攻击");

        pk::get_tech(技巧_防卫强化).desc = pk::encode("据点攻击伤害大幅提高、据点高度增加20点");

        // pk::get_tech(技巧_防卫强化).desc = pk::encode("大幅提高据点反击伤害");

        pk::get_tech(技巧_港关扩张).desc = pk::encode("提升据点容量,提高据点和县城金收入10%");

        pk::get_tech(技巧_木牛流马).desc = pk::encode("输送队移动增加,提高据点和县城粮收入10%");

        pk::get_tech(技巧_政令整备).desc = pk::encode("治安下降速度减慢、行动力回复量增加30%");

        pk::get_tech(技巧_掌握人心).desc = pk::encode("忠诚不易下降、每月增加据点治安和士气5点");
      }
      else
      {
        pk::get_tech(技巧_枪兵锻练).desc = pk::encode(tech[技巧_枪兵锻练]);
        pk::get_tech(技巧_戟兵锻练).desc = pk::encode(tech[技巧_戟兵锻练]);
        pk::get_tech(技巧_弩兵锻练).desc = pk::encode(tech[技巧_弩兵锻练]);
        pk::get_tech(技巧_骑兵锻练).desc = pk::encode(tech[技巧_骑兵锻练]);
        pk::get_tech(技巧_奇袭).desc = pk::encode(tech[技巧_奇袭]);
        pk::get_tech(技巧_矢盾).desc = pk::encode(tech[技巧_矢盾]);
        pk::get_tech(技巧_大盾).desc = pk::encode(tech[技巧_大盾]);
        pk::get_tech(技巧_强弩).desc = pk::encode(tech[技巧_强弩]);
        pk::get_tech(技巧_良马产出).desc = pk::encode(tech[技巧_良马产出]);
        pk::get_tech(技巧_骑射).desc = pk::encode(tech[技巧_骑射]);
        pk::get_tech(技巧_防卫强化).desc = pk::encode(tech[技巧_防卫强化]);
        pk::get_tech(技巧_港关扩张).desc = pk::encode(tech[技巧_港关扩张]);
        pk::get_tech(技巧_木牛流马).desc = pk::encode(tech[技巧_木牛流马]);
        pk::get_tech(技巧_政令整备).desc = pk::encode(tech[技巧_木牛流马]);
        pk::get_tech(技巧_掌握人心).desc = pk::encode(tech[技巧_掌握人心]);
      }
    }

    // void onTurnStart(pk::force @force)
    // {
    //   if (is_player_effect(force) and pk::has_tech(force, 技巧_防卫强化))
    //   {
    //     pk::list<pk::city @> city_list = pk::get_city_list(force);
    //     for (int i = 0; i < int(city_list.count); i++)
    //     {
    //       pk::city @city = city_list[i];
    //       int range_distance = 2;
    //       if (pk::has_tech(force, 技巧_强弩))
    //         range_distance = 3;
    //       array<pk::point> rings = pk::range(city.get_pos(), 1, range_distance);
    //       for (int m = 0; m < int(rings.length); m++)
    //       {
    //         pk::point dst_pos = rings[m];
    //         pk::unit @dst = pk::get_unit(dst_pos);
    //         if (dst !is null and dst.get_force_id() != force.get_force_id() and !force.ally[dst.get_force_id()])
    //         {
    //           int energy_diff = pk::max(1, int((1.2 - pk::get_person(dst.leader).stat[武将能力_统率] * 0.006)));
    //           pk::add_energy(dst, -energy_diff, true);
    //         }
    //       }
    //     }
    //   }
    // }

    int func53(pk::unit @unit, pk::tactics @tactic, int type)
    {
      int result = prev_callback_53(unit, tactic, type);
      pk::force @force = pk::get_force(unit.get_force_id());
      if (is_player_effect(force) and pk::has_tech(force, 技巧_强弩) and unit.weapon == 兵器_弩)
      {
        result -= int(result * 0.1f);
      }
      return result;
    }

    int func150(pk::city @city)
    {
      int result = prev_callback_150(city);
      pk::force @force = pk::get_force(city.get_force_id());
      if (is_player_effect(force) and pk::has_tech(force, 技巧_木牛流马))
        result += int(0.1f * result);
      return result;
    }

    int func151(pk::city @city)
    {
      int result = prev_callback_151(city);
      pk::force @force = pk::get_force(city.get_force_id());
      if (is_player_effect(force) and pk::has_tech(force, 技巧_港关扩张))
        result += int(0.1f * result);
      return result;
    }

    int func152(pk::building @building, int city_revenue)
    {
      int result = prev_callback_152(building, city_revenue);
      pk::force @force = pk::get_force(building.get_force_id());
      if (is_player_effect(force) and pk::has_tech(force, 技巧_木牛流马))
        result += int(0.2f * result);
      return result;
    }

    int func153(pk::building @building, int city_harvest)
    {
      int result = prev_callback_153(building, city_harvest);
      pk::force @force = pk::get_force(building.get_force_id());
      if (is_player_effect(force) and pk::has_tech(force, 技巧_港关扩张))
        result += int(0.2f * result);
      return result;
    }

    int func162(pk::district @district)
    {
      int result = prev_callback_162(district);
      pk::force @force = pk::get_force(district.get_force_id());
      if (is_player_effect(force) and pk::has_tech(force, 技巧_政令整备))
      {
        return result += int(result * 0.3f);
      }
      return result;
    }

    void func209(pk::damage_info& info, pk::unit @attacker, int tactics_id, const pk::point& in target_pos, int type, int critical, bool ambush, int rettype)
    {
      prev_callback_209(info, attacker, tactics_id, target_pos, type, critical, ambush, rettype);

      if (开启_科技加强包 and rettype != 15)
      {
        pk::force @force = pk::get_force(attacker.get_force_id());
        pk::unit @target = pk::get_unit(target_pos);
        pk::hex @unit_hex = pk::get_hex(attacker.get_pos());
        if (is_player_effect(force) and attacker.weapon == 兵器_战马 and pk::get_distance(attacker.pos, target_pos) > 1)
          技巧_骑射_加强(info, force);
        if (is_player_effect(force) and attacker.weapon == 兵器_枪 and unit_hex.terrain == 地形_森)
          技巧_奇袭_加强(info, force);
        if (is_player_effect(force) and target !is null and target.weapon == 兵器_戟 and attacker !is null and rettype != 15 and type != 0)
          技巧_大盾_加强(info, target);
        if (is_player_effect(force) and target !is null and target.weapon == 兵器_戟 and pk::get_distance(attacker.pos, target_pos) > 1 and (target.weapon == 兵器_走舸 or target.weapon == 兵器_弩 or target.weapon == 兵器_井阑))
          技巧_矢盾_加强(info, target);
      }
    }

    void onMonthStart()
    {
      for (int i = 0; i < 据点_末; i += 1)
      {
        pk::building @building = pk::get_building(i);
        int force_id = building.get_force_id();
        if (pk::is_valid_force_id(force_id) and force_id < 非贼势力_末)
        {
          pk::force @force = pk::get_force(force_id);
          if (is_player_effect(force) and pk::has_tech(force, 技巧_掌握人心))
          {
            pk::add_energy(building, 掌握人心回复气力数, true);
            ch::add_public_order(building, 掌握人心回复治安数, true);
          }
        }
      }
    }

    void onNewDay()
    {
    }

    void 技巧_奇袭_加强(pk::damage_info& info, pk::force @force)
    {
      if (pk::has_tech(force, 技巧_奇袭))
        info.energy_heal += 10;
    }

    void 技巧_骑射_加强(pk::damage_info& info, pk::force @force)
    {
      if (pk::has_tech(force, 技巧_骑射))
        info.energy_damage += 3 + info.troops_damage / 100;
    }

    void 技巧_大盾_加强(pk::damage_info& info, pk::unit @unit)
    {
      pk::force @force = pk::get_force(unit.get_force_id());
      if (is_player_effect(force) and pk::has_tech(force, 技巧_大盾))
        pk::add_energy(unit, 3, true);
    }

    void 技巧_矢盾_加强(pk::damage_info& info, pk::unit @unit)
    {
      pk::force @force = pk::get_force(unit.get_force_id());
      if (is_player_effect(force) and pk::has_tech(force, 技巧_矢盾))
        info.troops_damage = int(info.troops_damage * 0.7);
    }

  } Main main;
}
